package com.vcredit.creditcat.manager.ability;

import com.vcredit.creditcat.util.EnumExtUtil;
import com.vcredit.framework.annotation.Log;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.vcredit.creditcat.api.ICustAbilityManager;
import com.vcredit.creditcat.dto.ability.AbilityDto;
import com.vcredit.creditcat.dto.ability.CreditDimensionDto;
import com.vcredit.creditcat.dto.creditrepository.AuthItemDto;
import com.vcredit.creditcat.dto.creditrepository.ItemStatusDto;
import com.vcredit.creditcat.enumtype.AbilityEnum;
import com.vcredit.creditcat.enumtype.AbilityLoanCardCountEnum;
import com.vcredit.creditcat.manager.CreditCatProcessManager;
import com.vcredit.creditcat.model.Ability;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthProccess;
import com.vcredit.creditcat.model.CreditDimension;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAbility;
import com.vcredit.creditcat.model.CustDimension;
import com.vcredit.creditcat.service.AbilityService;
import com.vcredit.creditcat.service.AuthItemService;
import com.vcredit.creditcat.service.AuthProccessService;
import com.vcredit.creditcat.service.CreditDimensionService;
import com.vcredit.creditcat.service.CustAbilityService;
import com.vcredit.creditcat.service.CustCreditRepositoryService;
import com.vcredit.creditcat.service.CustDimensionService;
import com.vcredit.creditcat.service.CustProductApplyService;
import com.vcredit.creditcat.service.CustRecommendCardService;
import com.vcredit.creditcat.service.product.CustLoanProductService;
import com.vcredit.framework.util.BeanUtil;
import com.vcredit.framework.util.BeanUtilFilter;

@Service(protocol = { "protocol1" }, version = "1.0")
public class CustAbilityManager implements ICustAbilityManager {

	@Autowired
	private AbilityService abilityService;

	@Autowired
	private CreditDimensionService creditDimensionService;

	@Autowired
	private CustAbilityService custAbilityService;

	@Autowired
	private CustDimensionService custDimensionService;

	@Autowired
	private AuthItemService authItemService;

	@Autowired
	private AuthProccessService authProccessService;

	@Autowired
	private CustCreditRepositoryService custCreditRepositoryService;
	
	@Autowired
	private CustProductApplyService custProductApplyService;
	
	@Autowired
	private CustRecommendCardService custRecommendCardService;
	
	@Autowired
	private CreditCatProcessManager creditCatProcessManager;
	
	@Autowired
	private CustLoanProductService custLoanProductService;

	@Override
	public List<AbilityDto> findAllAbilities() {
		Map<Long, Ability> abilities = abilityService.findAll();
		List<AbilityDto> result = BeanUtil.copy(abilities.values(), AbilityDto.class,
				new BeanUtilFilter<AbilityDto, Ability>() {
					@Override
					public AbilityDto filter(Ability source, AbilityDto target) {
						// 获取特权需要的认证项目
						List<AuthItem> authItems = authItemService.getItemByCodes(source.getMinCode());
						target.setAuthItems(BeanUtil.copy(authItems, AuthItemDto.class));
						return target;
					}
				});
		return result;
	}

	@Override
	public List<AbilityDto> findCustOwnAbilities(Cust cust) {
		// 获取用户拥有的特权
		List<CustAbility> ownAbilities = custAbilityService.findByCustId(cust.getCustId());

		return getCustOwnedAbility(ownAbilities, false);
	}
	
	@Override
	public List<CustAbility> findCustAbilities(Cust cust) {
		// 获取用户拥有的特权
		List<CustAbility> ownAbilities = custAbilityService.findByCustId(cust.getCustId());
		return ownAbilities;
	}

	@Override
	public List<CreditDimensionDto> findCustOwnDimension(Cust cust) {
		// 获取用户的维度信用指数
		List<CustDimension> ownDimensions = custDimensionService.findByCustId(cust.getCustId());

		return getCustCreditDimension(ownDimensions);
	}

	/**
	 * 获取用户拥有的特权
	 * 
	 * @param ownAbilities
	 * @param isItemClude
	 *            是否包含认证项
	 * @return
	 */
	private List<AbilityDto> getCustOwnedAbility(List<CustAbility> ownAbilities, final boolean isItemClude) {
		List<AbilityDto> abilityDtos = new ArrayList<AbilityDto>();

		for (CustAbility custAbility : ownAbilities) {
			AbilityDto abilityDto = new AbilityDto();
			BeanUtil.copy(custAbility.getAbility(), abilityDto, new BeanUtilFilter<AbilityDto, Ability>() {
				@Override
				public AbilityDto filter(Ability source, AbilityDto target) {
					if (isItemClude) {
						// 获取特权需要的认证项目
						List<AuthItem> authItems = authItemService.getItemByCodes(source.getMinCode());
						target.setAuthItems(BeanUtil.copy(authItems, AuthItemDto.class));
					}
					return target;
				}
			});
			abilityDtos.add(abilityDto);
		}
		return abilityDtos;
	}

	/**
	 * 获取用户的维度信用指数
	 * 
	 * @param ownDimensions
	 * @return
	 */
	private List<CreditDimensionDto> getCustCreditDimension(final List<CustDimension> ownDimensions) {
		// 获取所有信用维度
		List<CreditDimension> allDimensions = creditDimensionService.findAll();

		List<CreditDimensionDto> creditDimensionDtos = BeanUtil.copy(allDimensions, CreditDimensionDto.class,
				new BeanUtilFilter<CreditDimensionDto, CreditDimension>() {
					@Override
					public CreditDimensionDto filter(CreditDimension source, CreditDimensionDto target) {
						target.setDimensionScore(0);
						for (CustDimension custDimension : ownDimensions) {
							if (custDimension.getDimensionId().equals(source.getDimensionId())) {
								target.setDimensionScore(custDimension.getDemensionScore());
							}
						}
						return target;
					}

				});

		return creditDimensionDtos;
	}

	@Override
	public List<AuthItemDto> findRecommendAuthItem(Cust cust, int top) throws Exception {
		AuthProccess authProccess = authProccessService.findByProcessId(cust.getLastProccessId());

		List<AuthItem> authItems = authItemService.findAllAuthItems();// 查询所有认证项

		List<AuthItemDto> response = new ArrayList<AuthItemDto>();

		Collections.sort(authItems, new Comparator<AuthItem>() {
			@Override
			public int compare(AuthItem item1, AuthItem item2) {
				if (item1.getItemPriority() > item2.getItemPriority())
					return 1;
				else
					return -1;
			}
		});

		for (int i = 0, size = authItems.size(); i < size; i++) {

			if (top == i) {
				break;
			}

			AuthItem authItem = authItems.get(i);
			int bs = 0;// 0 未完成 1已完成 2审核中
			if (1 == (authProccess.getSuccessCode() & authItem.getAuthCode())) {
				bs = 1;// 运算结果为1表示已完成
			} else {// 当运算结果为0的时候需要区分一下是未完成还是审核中
				ItemStatusDto ret = custCreditRepositoryService.getStatus(authItem.getAuthCode().toString(), 0, cust);
				if (ret.getStatus().equals("0")) {
					bs = 0;// 未完成
				} else if (ret.getStatus().equals("1")) {// 成功
					bs = 1;
				} else if (ret.getStatus().equals("3")) {// 失败
					bs = 0;
				} else if (ret.getStatus().equals("2")) {// 认证中
					bs = 2;
				}
			}
			response.add(new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(), bs));
		}
		return response;
	}
	
	
	public List<AuthItemDto> findRecommendAuthItem(Cust cust) throws Exception {
		AuthProccess authProccess = authProccessService.findByProcessId(cust.getLastProccessId());

		List<AuthItem> authItems = authItemService.findAllAuthItems();// 查询所有认证项

		List<AuthItemDto> response = new ArrayList<AuthItemDto>();

		Collections.sort(authItems, new Comparator<AuthItem>() {
			@Override
			public int compare(AuthItem item1, AuthItem item2) {
				if (item1.getItemSort() > item2.getItemSort())
					return 1;
				else
					return -1;
			}
		});

		for (int i = 0, size = authItems.size(); i < size; i++) {

			AuthItem authItem = authItems.get(i);
			
			if(!authItem.getIsRepository()){
				continue;
			}
			
			int bs = 0;// 0 未完成 1已完成 2审核中
			if (1 == (authProccess.getSuccessCode() & authItem.getAuthCode())) {
				bs = 1;// 运算结果为1表示已完成
			} else {// 当运算结果为0的时候需要区分一下是未完成还是审核中
				ItemStatusDto ret = custCreditRepositoryService.getStatus(authItem.getAuthCode().toString(), 0, cust);
				if (ret.getStatus().equals("0")) {
					bs = 0;// 未完成
				} else if (ret.getStatus().equals("1")) {// 成功
					bs = 1;
				} else if (ret.getStatus().equals("3")) {// 失败
					bs = 0;
				} else if (ret.getStatus().equals("2")) {// 认证中
					bs = 2;
				}
			}
			response.add(new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(), bs,authItem.getAuthCode().toString()							));
		}
		return response;
	}

	@Override
	public void addAbility(String privilegeId, Long custId) throws Exception {
		Long abilityId = Long.parseLong(privilegeId);
		int loanCount = custLoanProductService.getSuccessLoanCount(custId);
		int cardCount = custRecommendCardService.countApplyRecord(custId);
		int totalCount = loanCount+cardCount;
		if(abilityId==AbilityEnum.Silver.getCode() && totalCount<AbilityLoanCardCountEnum.Silver.getCode()){
			throw new Exception("银卡权益申请失败");
		}else if(abilityId==AbilityEnum.Gold.getCode() && totalCount<AbilityLoanCardCountEnum.Gold.getCode()){
			throw new Exception("金卡权益申请失败");
		}else if(abilityId==AbilityEnum.Platinum.getCode() && totalCount<AbilityLoanCardCountEnum.Platinum.getCode()){
			throw new Exception("白金卡权益申请失败");
		}else if(abilityId==AbilityEnum.Diamond.getCode() && totalCount<AbilityLoanCardCountEnum.Diamond.getCode()){
			throw new Exception("钻石卡权益申请失败");
		}		
		creditCatProcessManager.addAbility(abilityId, custId);
	}

	@Log
	@Override
	public String getCustMaxAbilityValue(Long custId) throws Exception {
		CustAbility maxAbilityByCustId = custAbilityService.findMaxAbilityByCustId(custId);
		if (null == maxAbilityByCustId)
			return "";
		Long abilityId = maxAbilityByCustId.getAbilityId();
		AbilityEnum abilityEnum = EnumExtUtil
				.getEnumOnValue(AbilityEnum.class, String.valueOf(abilityId), "code");
		return MessageFormat.format("贷款成功返{0}元",abilityEnum.getAmt()/100);
	}

}
